package com.dy.design_pattern_study.store_cashier_system;

import com.dy.design_pattern_study.store_cashier_system.factory.CashSuper;
import com.dy.design_pattern_study.store_cashier_system.factory.impl.CashNormal;
import com.dy.design_pattern_study.store_cashier_system.factory.impl.CashRebate;
import com.dy.design_pattern_study.store_cashier_system.factory.impl.CashReturn;

import java.util.Scanner;

/**
 * @CreateBy zhangdingyi
 * @Date 2023-03-09
 * @Content 利用策略模式改写商场收银系统
 * 策略模式的优点
 * 1.策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。
 * 继承有助于析取出这些算法中的公共功能
 *
 * 2.策略模式的优点是简化了单元测试，因为每个算法都有自己的类，可以通过自己的接口单独测试
 *
 * 3.当不同的行为堆砌在一个类中时，就很难避免使用条件语句来选择合适的行为。
 * 将这些行为封装在一个个独立的Strategy类中，可以在使用这些行为的类中消除条件语句
 *
 * 4.策略模式就是用来封装算法的，但在实践中，我们发现可以用它来封装几乎任何类型的规则，
 * 只要在分析过程中听到需要在不同时间应用不同的业务规则，就可以考虑使用策略模式处理这种变化的可能性
 *
 * 简而言之，策略模式就是提取出特征封装起来，供其他方法选用
 *
 *
 */
public class CashContext {
    private CashSuper cashSuper;

    //传入具体的收费策略 -简单的讲策略模式就是新建不同的对象，可以设置对应的对象
    public CashContext(CashSuper cashSuper){
        this.cashSuper = cashSuper;
    }

    //这里设置对象的方法
    public double GetResult(double money){
        return cashSuper.acceptCash(money);
    }

    //策略模式的前台
    public static void main(String[] args) {
        CashContext context = null;

        System.out.println("*********** 欢迎进入 超市收银系统 ***********");

        System.out.println("1." + CashFactory.NORMAL_CHARGE);
        System.out.println("2." + CashFactory.RETURN_MONEY);
        System.out.println("3." + CashFactory.REBATE_MONEY);

        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("请选择对应的收费活动：");

            int inType = scanner.nextInt();

            switch (inType) {
                case 1:
                    context = new CashContext(new CashNormal());
                    CashFactory.showType = CashFactory.NORMAL_CHARGE;
                    break;
                case 2:
                    context = new CashContext(new CashReturn("300", "100"));
                    CashFactory.showType = CashFactory.RETURN_MONEY;
                    break;
                case 3:
                    context = new CashContext(new CashRebate("0.8"));
                    CashFactory.showType = CashFactory.REBATE_MONEY;
                    break;
            }


            System.out.println("请输入商品价格：");
            double price = scanner.nextDouble();

            System.out.println("请输入商品数量：");
            double number = scanner.nextInt();

            double totalPrices = context.GetResult(price * number) ;

            System.out.println("操作： " + CashFactory.showType);
            System.out.println("单价 = " + price);
            System.out.println("总价 = " + totalPrices);
            //可以把数据添加到一个集合就可以进行多次显示

            System.out.println("是否继续输入？Y/N");
            String conti = scanner.next();

            if (conti.equalsIgnoreCase("N")) {
                scanner.close();
                break;
            }
        }
    }

}
